﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using System.Threading;
using System.DirectoryServices;
using System.Collections;

using groupAnalyzer.Observers;
using groupAnalyzer.connectivity;
using groupAnalyzer.model;

namespace groupAnalyzer.controller
{
    public class SearchController : ObserverClient
    {
        private Observer observer;
        private Factory factory;
        private Messages message;
        private object payLoad;
        private Thread myThread;

        public void notify(Messages message, Object payLoad)
        {
            this.message = message;
            this.payLoad = payLoad;
            if (this.myThread.ThreadState == ThreadState.Suspended)
                this.myThread.Resume();

        }

        private void searchGroup(string groupName)
        {
            this.factory.resetGroups();

            LdapConnectivity connectivity = LdapConnectivity.constructLdapConnectivity();
            List<DirectoryEntry> groupsRaw = null;
            if (groupName.Equals(""))
            {
                groupsRaw = connectivity.getAllGroups();
            }
            else
            {
                groupsRaw = connectivity.searchGroup(groupName);
            }
            foreach (DirectoryEntry groupRaw in groupsRaw)
            {
                string nameOfGroupL = connectivity.getProperty(groupRaw, "name", 0);
                string fqdn = connectivity.getProperty(groupRaw, "distinguishedName", 0); ;

                Group group = this.factory.constructGroup(nameOfGroupL, fqdn);
            }
            // finished work
            this.observer.notifiy(Messages.searched, null);
        }

        public void run()
        {
            while (true)
            {
                if (this.message == Messages.nothing)
                {
                    // be nice to cpu
                    this.myThread.Suspend();
                }
                switch (this.message)
                {
                    case Messages.buildTree:

                        this.observer.notifiy(Messages.finishedBuildTree, null);
                        break;

                    case Messages.search:
                        string groupName = (string)this.payLoad;
                        this.searchGroup(groupName);
                        break;

                    case Messages.exit:
                        Environment.Exit(0);
                        break;

                    default:
                        Console.WriteLine("unimplemented message " + message.ToString());
                        break;

                    case Messages.analyze:
                    case Messages.refresh:
                    case Messages.analyzed:
                    case Messages.nothing:
                        break;
                }
                // nothing to do any more - set it to nothing
                this.message = Messages.nothing;
            }
        }

        public SearchController(Observer observer, Factory factory)
        {
            this.observer = observer;
            this.factory = factory;

            this.message = Messages.nothing;
            this.observer.register(this);

            this.myThread = new Thread(new ThreadStart(this.run));
            myThread.Start();
        }

        public static void init(Observer observer, Factory factory)
        {
            SearchController searchController = new SearchController(observer, factory);
        }
    }
}
